org 100h
jmp LF0
global0 dw 4 dup(0)

mientras1:
mov cx, [bp-12]

push ax
mov ax, cx
mov cx, 4

cmp ax, cx
pop ax
jb bloquem1
jmp finmientras1
bloquem1:
mov cx, 2

push cx;param1
mov cx, [bp-12]

push cx;param2
call multN
pop cx

;------- Begin array assignment --------
mov ax, [bp-12]
mov bx, 2
mul bx
mov si, ax
mov global0[si], cx
;------- End array assignment --------

mov cx, [bp-12]

push cx;param1
mov cx, 1

push cx;param2
call sumaN
pop cx

mov [bp-12], cx
jmp mientras1

mientras2:
mov cx, [bp-12]

push ax
mov ax, cx
mov cx, 4

cmp ax, cx
pop ax
jb bloquem2
jmp finmientras2
bloquem2:
push ax
push offset cadena1
push 7
call writeSTR
pop ax
push ax
;------- Begin array variable --------
mov cx, [bp-12]

mov ax, cx
mov bx, 2
mul bx
mov si, ax
mov cx, global0[si]
;------- End array variable --------


push 0000h
push cx
call writeNUM
pop ax
call writeCRLF
mov cx, [bp-12]

push cx;param1
mov cx, 1

push cx;param2
call sumaN
pop cx

mov [bp-12], cx
jmp mientras2

cadena1 dw "'num: '";7


LF0:
;armo registro activacion
push ax;Push ax, para no perderlo
mov ax, bp;Push bp a ax, para no perderlo
mov bp, sp
sub sp, 12;reservo temporales y variables locales
pushf;push estado flags
push ax;push data link
push ax;push control link y luego parametros
sub sp, 2;espacio etorno
call F0
pop cx;retorno en cx
add sp, 0
pop bp;restauro bp
add sp,2;chau datalink
popf
add sp, 12
mov bp, ax
pop ax
F0 proc near
mov cx, 5

;------- Begin array assignment --------
mov ax, 0
mov bx, 2
mul bx
mov si, ax
mov global0[si], cx
;------- End array assignment --------

mov cx, 1

mov [bp-12], cx
jmp mientras1
finmientras1:
mov cx, 0

mov [bp-12], cx
jmp mientras2
finmientras2:

fin: 
mov ah,4Ch
int 21h
errMn   dw  "Error multiplicar naturales (Overflow)" ;38
;multiplicacion de naturales
;
;   param1: mult1
;   param2: mult2
;
;   retorna el resultado en la punta del Stack
multN proc near
    push bp
    mov bp,sp
    push ax
    push dx
    
    mov ax, [bp+4]
    mov dx, [bp+6]
    mul dx
    jnc mulNok
    push offset errMn
    push 38
    call writeSTR
    jmp fin
mulNok:
    ;multiplica bien
    mov [bp+6],ax
    pop dx
    pop ax
    pop bp
    ret 2
multN endp


errorsn dw "Error al sumar naturales(Overflow)" ;34
;suma de dos numeros entero
;   con control de carry (no importa el flag signo)
;
;   param1: sumando1
;   param2: sumando2
;Deja en la punta del SP el resultado!!!
sumaN proc near
    push bp
    mov bp,sp
    push ax
    
    mov ax,[bp+4]
    add [bp+6],ax
    jnc sumnok
    push offset errorsn
    push 34
    call writeSTR
    jmp fin
sumnok:
    pop ax
    pop bp
    ret 2
sumaN endp
;Fin rutina suma natural


; ***Comienzo rutina writeNUM***
;
; Imprime por pantalla un numero (word con signo) sin <Enter> al final
; (usa rutina writeSTR)
;
; Parametro entrada 1: tipo de aritmetica -0000h=sin signo, 0001h=con signo- (word/via push del llamador)
; Parametro entrada 2: numero a imprimir (word/via push del llamador)
;
writeNUM proc near
    push bp
    mov bp, sp
    sub sp, 1        ; "variable local" [bp-1] = signo (00h=positivo, 01h=negativo)
    sub sp, 6        ; "variable local" [bp-7] = espacio para imprimir (db 6 dup(?))
    push ax
    push bx
    push cx
    push dx
    push si
    
    mov [bp-1], 00h
    mov ax, [bp+4]
    
    cmp [bp+6], 0
    je comenzar      ; Si no es aritmetica con signo, comienza
    cmp ax, 0
    jge comenzar     ; Si no es negativo, comienza
    neg ax           ; Realiza ax = -ax
    mov [bp-1], 01h
    
comenzar:
    mov bx, 10
    mov cx, 0
    mov si, bp
    sub si, 8
proxdiv:
    dec si
    xor dx, dx    
    div bx
    add dl, 48
    mov [si], dl
    inc cx
    cmp ax, 0
    jnz proxdiv
    
    cmp [bp-1], 00h
    jz mostrar
    
    dec si
    mov [si], '-'
    inc cx
mostrar:    
    push si
    push cx
    call writeSTR
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
    mov sp, bp   
    pop bp
    ret 4
writeNUM endp
;
; ***Fin rutina writeNUM***
; ***Comienzo rutina writeSTR***
;
; Imprime por pantalla un string sin <Enter> al final
;
; Parametro entrada 1: direccion de memoria donde comienza el string a imprimir (word/via push del llamador)
; Parametro entrada 2: cantidad de caracteres del string (word/via push del llamador)
;
writeSTR proc near
    push bp
    mov bp, sp
    push ax
    push bx
    push cx
    push si
    mov si, [bp+6]  ; a SI se le asigna el primer parametro (direccion)
    mov cx, [bp+4]  ; a CX se le asigna el segundo parametro (cantidad de caracteres)
    xor bx, bx
    
loop:    
    mov al, [si]
    mov ah, 0Eh
    int 10h     
    inc bx
    inc si
    cmp bx, cx
    jne loop
    pop si
    pop cx
    pop bx
    pop ax
    pop bp
    ret 4
writeSTR endp
;
; ***Fin rutina writeSTR***
ret


;imprime un enter
writeCRLF proc near
    push ax
    
    mov al, 0Dh
    mov ah, 0Eh
    int 10h     
    mov al, 0Ah
    mov ah, 0Eh
    int 10h     
    pop ax
    ret
writeCRLF endp


